﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;
using System.Speech.Synthesis;
using System.Runtime.InteropServices;
using System.IO;

namespace DelicateDict.Classes
{
    class Speak : Form
    {

        #region declare all properties of class
        //============ global variable for speaking word at Text To Speech Mode ==========/
        public static SpeechSynthesizer sp = null; // It's static to have only one instance
        public static int VoiceId = 0;


        //============ variable for nutural speech mode ====================/

        // Import API Function in DLL
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr GetModuleHandle(string name);
        [DllImport("winmm.dll", CharSet = CharSet.Auto)]
        public static extern int waveOutGetVolume(IntPtr hwnd, out uint dwVolume);
        [DllImport("winmm.dll", CharSet = CharSet.Auto)]
        public static extern int waveOutSetVoume(Int16 hwnd, uint dwVolume);
        [DllImport("winmm.dll")]
        public static extern int mciSendString(string command, StringBuilder buffer, int buffersize, IntPtr hWndCallback);
        private const int MM_MCINOTIFY = 953;

        // global variable
        readonly string FolderPathOfSpeech = Directory.GetCurrentDirectory() + @"\LingoesEnglish";
        public static IntPtr SpeakHandle = IntPtr.Zero;

        #endregion

        #region function of class
        /// <summary>
        /// contructor for speech class.It wil:
        /// Create instance of speakvoice
        /// Load VoiceList
        /// SetVoice list depend on VoiceId
        /// </summary>
        public Speak()
        {
            sp = new SpeechSynthesizer();
            //GetListVoice();
           // SetVoice(VoiceId);
        }
       /* private void GetListVoice()
        {
            
            ListVoice = new List<string>();
            ISpeechObjectTokens sots = sp.GetVoices("", "");
            foreach (ISpeechObjectToken sot in sots)
            {
                ListVoice.Add(sot.GetAttribute("Name"));
            }
        }
        public void SetVoice(int t)
        {
            sp.Voice = sp.GetVoices("", "").Item(t);
            VoiceId = t;
        }*/
        public void SpeakAsTTS(string sw)
        {
            // sp.Speak(sw, SpeechVoiceSpeakFlags.SVSFDefault);
            sp.SpeakAsync(sw);
        }
        //======= natural speech==============//
        private string FilePath(string WordName)
        {
            string File = FolderPathOfSpeech + @"\" + WordName[0].ToString().ToUpper() + @"\" + WordName + ".mp3";
            return FolderPathOfSpeech + @"\" + WordName[0].ToString().ToUpper() + @"\" + WordName + ".mp3";
        }
        private bool IsHaveFileSpeech(string WordName)
        {

            return (File.Exists(FilePath(WordName)));

        }
        public void SpeakAsNS(string WordName)
        {

            string command = "open \"" + FilePath(WordName) + "\" type mpegvideo alias MediaFile";
            mciSendString(command, null, 0, IntPtr.Zero);
            mciSendString("play MediaFile notify", null, 0, base.Handle);
            //  mciSendString("play Mediafile", null, 0,SpeakHandle);

        }
        // Override the WndProc function in the form
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == MM_MCINOTIFY)
            {
                mciSendString("Close MediaFile", null, 0, IntPtr.Zero);
            }

            base.WndProc(ref m);
        }
        private static void CloseWhenDone(ref Message m)
        {
            if (m.Msg == MM_MCINOTIFY)
            {
                mciSendString("Close MediaFile", null, 0, IntPtr.Zero);
            }
        }
        //======= speak word ===========/
        public void SpeakWord(string WordName)
        {
            if (IsHaveFileSpeech(WordName))
            {
                SpeakAsNS(WordName);
            }
            else
            {
                SpeakAsTTS(WordName);
            }
        }
        #endregion
    }
}
